local skynet = require "skynet"
local waitlist={}
local ready_count={}
local wait_count={}
local event_status={}
local run_count={}

local START=1
local TRIGGERED=2

local function cmp(a,b)
    return a.n<b.n
end
local function check(event)
    skynet.sleep(500)
    while run_count[event]<wait_count[event] do
        skynet.error(string.format("warning:service event[%d] blocking,run_count:%d,wait_count:%d",event,run_count[event],wait_count[event]))
        skynet.sleep(6000)
    end
end
local function on_event(event)
    if event_status[event] ~= START or wait_count[event]~=ready_count[event] then
        return
    end
    event_status[event]=TRIGGERED
    skynet.error(string.rep("=",20).." service.on_event:"..event.." "..string.rep("=",20))
    assert(waitlist[event])
    table.sort(waitlist[event],cmp)
    skynet.fork(check,event)
    for k,v in pairs(waitlist[event]) do
        local ok=v.r(true)
        if not ok then
            skynet.error(string.format("warn: event[%d] call back failed,count:%d,weight:%d",event,k,v.n))
        end
        skynet.wait(event.."_waitlist")
    end
end

function wait.wait(event,n)
    if event_status[event] == TRIGGERED then
        error(string.format("event[%d] already triggered",event))
    end
    wait_count[event]=(wait_count[event] or 0)+1
    if not waitlist[event] then
        waitlist[event] = {}
    end
    table.insert(waitlist[event],{n=n or 0,r=skynet.response()})
    on_event(event)
end

function response.ready(event)
    if event_status[event] == TRIGGERED then
        error(string.format("event[%d] already triggered",event))
    end

    ready_count[event]=(ready_count[event] or 0)+1
end


function response.next(event)
    run_count[event]=(run_count[event] or 0)+1
    skynet.wakeup(event.."_waitlist")
end

function response.on_event(event)
    event_status[event]=START
    on_event(event)
end

function init()

end

function exit()

end